package cn.edu.xmu.oomall.aftersales.controller;

import cn.edu.xmu.oomall.aftersales.constant.TimeFormat;
import cn.edu.xmu.oomall.aftersales.model.vo.*;
import cn.edu.xmu.oomall.aftersales.service.AfterSaleService;

import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import io.swagger.annotations.*;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import static cn.edu.xmu.oomall.core.util.Common.processFieldErrors;

/**
 * @author Jiawei Zheng
 * @author zyu
 * @date 2021-12-11
 */
@RestController
@Slf4j
@RefreshScope
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class AfterSaleController {

    @Autowired
    AfterSaleService afterSaleService;

    @Autowired
    private HttpServletResponse httpServletResponse;


    @ApiOperation(value = "获得售后单的所有状态")
    @ApiResponses(value = {@ApiResponse(code = 0, message = "成功")})
    @GetMapping("/aftersales/states")
    public Object getAllAfterSaleStates() {
        return Common.decorateReturnObject(afterSaleService.getAllAdvanceSaleStates());
    }

    /**
     * 买家提交售后单
     * @param userId
     * @param userName
     * @param id
     * @param vo
     * @param bindingResult
     * @return
     */
    @PostMapping("/orderitems/{id}/aftersales")
    @Audit
    public Object createAfterSale(@LoginUser Long userId,
                                  @LoginName String userName,
                                  @PathVariable("id") Long id,
                                  @Valid @RequestBody CreateAfterSaleVo vo,
                                  BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.createAfterSale(userId, userName, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 买家修改售后单信息
     * @param userId
     * @param userName
     * @param id
     * @param vo
     * @param bindingResult
     * @return
     */
    @PutMapping("/aftersales/{id}")
    @Audit
    public Object changeAfterSale(@LoginUser Long userId,
                                  @LoginName String userName,
                                  @PathVariable("id") Long id,
                                  @Valid @RequestBody ModifyAfterSaleVo vo,
                                  BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.changeAfterSale(userId, userName, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 买家取消售后单和逻辑删除售后单
     * @param userId
     * @param userName
     * @param id
     * @return
     */
    @DeleteMapping("/aftersales/{id}")
    @Audit
    public Object deleteAfterSale(@LoginUser Long userId,
                                  @LoginName String userName,
                                  @PathVariable("id") Long id){
        ReturnObject ret = afterSaleService.deleteAfterSale(userId, userName, id);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 买家填写售后运单信息
     * @param userId
     * @param userName
     * @param id
     * @param vo
     * @return
     */
    @PutMapping("/aftersales/{id}/sendback")
    @Audit
    public Object sendbackAfterSale(@LoginUser Long userId,
                                    @LoginName String userName,
                                    @PathVariable("id") Long id,
                                    @Valid @RequestBody SendBackAfterSaleVo vo,
                                    BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.sendbackAfterSale(userId, userName, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 买家确认售后单结束
     * @param userId
     * @param userName
     * @param id
     * @return
     */
    @PutMapping("/aftersales/{id}/confirm")
    @Audit
    public Object confirmAfterSale(@LoginUser Long userId,
                                   @LoginName String userName,
                                   @PathVariable("id") Long id){
        ReturnObject ret = afterSaleService.confirmAfterSale(userId, userName, id);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 管理员同意或不同意售后请求
     * @param userId
     * @param userName
     * @param shopId
     * @param id
     * @param vo
     * @return
     */
    @PutMapping("/shops/{shopId}/aftersales/{id}/confirm")
    @Audit(departName = "shops")
    public Object acceptAfterSale(@LoginUser Long userId,
                                  @LoginName String userName,
                                  @PathVariable("shopId") Long shopId,
                                  @PathVariable("id") Long id,
                                  @Valid @RequestBody AcceptAfterSaleVo vo,
                                  BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.acceptAfterSale(userId, userName, shopId, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 店家验收买家收到的退（换）货
     * @param userId
     * @param userName
     * @param shopId
     * @param id
     * @param vo
     * @return
     */
    @PutMapping("/shops/{shopId}/aftersales/{id}/receive")
    @Audit(departName = "shops")
    public Object receiveAfterSale(@LoginUser Long userId,
                                   @LoginName String userName,
                                   @PathVariable("shopId") Long shopId,
                                   @PathVariable("id") Long id,
                                   @Valid @RequestBody ReceiveAfterSaleVo vo,
                                   BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.receiveAfterSale(userId, userName, shopId, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 店家发货
     * @param userId
     * @param userName
     * @param shopId
     * @param id
     * @param vo
     * @return
     */
    @PutMapping("/shops/{shopId}/aftersales/{id}/deliver")
    @Audit(departName = "shops")
    public Object deliverAfterSale(@LoginUser Long userId,
                                   @LoginName String userName,
                                   @PathVariable("shopId") Long shopId,
                                   @PathVariable("id") Long id,
                                   @Valid @RequestBody DeliverAfterSaleVo vo,
                                   BindingResult bindingResult){
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        ReturnObject ret = afterSaleService.deliverAfterSale(userId, userName, shopId, id, vo);
        return Common.decorateReturnObject(ret);
    }

    /**
     * 买家根据售后单id查询售后单信息
     * @param aftersaleId
     * @param userid
     * @return
     */
    @ApiOperation(value = "买家根据售后单id查询售后单信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @GetMapping("/aftersales/{id}")
    public Object getAftersaleOrderByIdCustomer(@PathVariable("id") Long aftersaleId,
                                                @LoginUser Long userid) {
        return Common.decorateReturnObject(afterSaleService.customerSelectAfterSaleByid(userid,aftersaleId));
    }

    /**
     * 管理员根据售后单id查询售后单信息
     * @param aftersaleId
     * @param shopId
     * @return
     */
    @ApiOperation(value = "管理员根据售后单id查询售后单信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shop")
    @GetMapping("/shops/{shopId}/aftersales/{id}")
    public Object getAftersaleOrderByIdAdmin(@PathVariable("id") Long aftersaleId,
                                             @PathVariable("shopId") Long shopId) {
        return Common.decorateReturnObject(afterSaleService.adminSelectAfterSaleByid(shopId,aftersaleId));
    }

    /**
     * 买家查询所有的售后单信息（可根据售后状态选择）
     * @param beginTime
     * @param endTime
     * @param state
     * @param page
     * @param pageSize
     * @param userId
     * @return
     */
    @ApiOperation(value = "买家查询所有的售后单信息（可根据售后状态选择）")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @GetMapping("/aftersales")
    public Object customerGetAfterSaleByCondition(@RequestParam(required = false) @DateTimeFormat(pattern = TimeFormat.INPUT_DATE_TIME_FORMAT) ZonedDateTime beginTime,
                                                  @RequestParam(required = false) @DateTimeFormat(pattern = TimeFormat.INPUT_DATE_TIME_FORMAT) ZonedDateTime endTime,
                                                  @RequestParam(required = false) Byte state,
                                                  @RequestParam(required = false) Integer page,
                                                  @RequestParam(required = false) Integer pageSize,
                                                  @LoginUser Long userId) {
        LocalDateTime begintime=TimeFormat.ZonedDateTime2LocalDateTime(beginTime);
        LocalDateTime endtime=TimeFormat.ZonedDateTime2LocalDateTime(endTime);
        return Common.decorateReturnObject(afterSaleService.customerSelectAfterSale(userId,state,begintime,endtime,page,pageSize));
    }


    /**
     * 管理员查看所有售后单（可根据售后类型和状态选择）
     * @param shopId
     * @param beginTime
     * @param endTime
     * @param type
     * @param state
     * @param page
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "管理员查看所有售后单（可根据售后类型和状态选择）")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shop")
    @GetMapping("/shops/{id}/aftersales")
    public Object adminGetAfterSaleByCondition(@PathVariable("id") Long shopId,
                                               @RequestParam(required = false) @DateTimeFormat(pattern = TimeFormat.INPUT_DATE_TIME_FORMAT) ZonedDateTime beginTime,
                                               @RequestParam(required = false) @DateTimeFormat(pattern = TimeFormat.INPUT_DATE_TIME_FORMAT) ZonedDateTime endTime,
                                               @RequestParam(required = false) Byte type,
                                               @RequestParam(required = false) Byte state,
                                               @RequestParam(required = false) Integer page,
                                               @RequestParam(required = false) Integer pageSize) {
        LocalDateTime begintime=TimeFormat.ZonedDateTime2LocalDateTime(beginTime);
        LocalDateTime endtime=TimeFormat.ZonedDateTime2LocalDateTime(endTime);
        return Common.decorateReturnObject(afterSaleService.adminSelectAfterSale(shopId,state,type,begintime,endtime,page,pageSize));
    }

    /**
     * 获得售后单的的支付信息
     * @param aftersaleId
     * @param userId
     * @return
     */
    @ApiOperation(value = "获得售后单的的支付信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(paramType = "id", dataType = "Integer", name = "aftersaleId", value = "售后单ID", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @GetMapping("/aftersales/{id}/payments")
    public Object getAferSalePayments(@PathVariable("id") Long aftersaleId,
                                      @LoginUser Long userId) {
        return Common.decorateReturnObject(afterSaleService.getAfterSalePayments(userId,aftersaleId));
    }

    @ApiOperation(value = "获得售后单的的支付信息")
    @Audit
    @GetMapping("/internal/aftersales")
    public InternalReturnObject<AfterSaleRetVo> getAfterSaleBySn(@RequestParam String serviceSn) {
        return afterSaleService.getAfterSaleBySn(serviceSn);
    }
}
